/*
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <QDir>
#include <QPluginLoader>

#include "parserfactory.h"
#include "boardparser.h"
#include "log.h"
#include "../paths.h"

namespace Wishmaster
{
	QList<BoardParser*> ParserFactory::m_parsers = QList<BoardParser*>();

	ParserFactory::ParserFactory()
	{

	}

	ParserFactory::~ParserFactory()
	{
	}

	bool ParserFactory::loadPluginsFromDirectory(const QString& pluginDirectory)
	{
		log(llNormal, "Loading boardparser from directory: %s", qPrintable(pluginDirectory));
		bool found = false;
		QDir dir(pluginDirectory);
		foreach(const QString& filename, dir.entryList(QDir::Files))
		{
			log(llDebug, "Trying to load: %s", qPrintable(filename));
			QPluginLoader loader(dir.absoluteFilePath(filename));
			if(loader.isLoaded())
				continue;
			QObject* instance = loader.instance();
			if(instance)
			{
				BoardParser* parser = qobject_cast<BoardParser*>(instance);
				if(parser)
				{
					if(parserLoaded(parser->id()))
					{
						//delete parser;
						continue;
					}
					found = true;
					log(llNormal, "Loading parser: %s", qPrintable(parser->id()));
					m_parsers.append(parser);
				}
				else
					log(llDebug, "!parser");
			}
			else
				log(llDebug, "!instance: %s", qPrintable(loader.errorString()));
		}
		return found;
	}

	void ParserFactory::loadPlugins()
	{
		m_parsers.clear();
		if(loadPluginsFromDirectory("./plugins/boardparsers") ||
		   loadPluginsFromDirectory("../plugins/boardparsers")) // Try to find plugins from build directory first
			return;
		if(!loadPluginsFromDirectory(DefaultPath::parserPlugins()))
		{
			log(llError, "Unable to find parser plugins");
		}
	}

	BoardParser* ParserFactory::makeParser(const QString& id, const QString& chanName, const QString& boardname)
	{
		foreach(BoardParser* parser, m_parsers)
		{
			if(parser->id() == id)
				return parser->clone(chanName, boardname);
		}

		return NULL;
	}

	QStringList ParserFactory::parserList()
	{
		QStringList list;
		foreach(BoardParser* parser, m_parsers)
		{
			list.append(parser->id());
		}
		return list;
	}

	bool ParserFactory::parserLoaded(const QString& id)
	{
		foreach(BoardParser* parser, m_parsers)
		{
			if(parser->id() == id)
				return true;
		}
		return false;
	}
}
